//
//  PageConfig.swift
//  
//
//  Created by tank on 2021/10/9.
//

import Foundation
import UIKit
import SwiftUI
import RxRelay
import LibBase
import LibUI

public class PageConfig {
    public enum StatusBarType: String, Codable {
        case light
        case dark
        
        public var statusBarStyle: UIStatusBarStyle {
            switch self {
            case .light:
                return .lightContent
            case .dark:
                return .`default`
            }
        }
    }
    
    public enum TitleAlignment: String, Codable {
        case left
        case center
        case right
        
        public var textAlignment: NSTextAlignment {
            switch self {
            case .left:
                return .left
                
            case .center:
                return .center
                
            case .right:
                return .right
            }
        }
    }
    
    public let name: String?
    
    public private(set) var title: String?
    
    public private(set) var subTitle: String?
    
    public var titleAlignment: TitleAlignment
    
    public var imageUrl: String?
    
    public var image: UIImage?
    
    public var selectedImage: UIImage?
    
    public var statusBarType: BehaviorRelay<StatusBarType>
    
    public var navigationBarStyle: BehaviorRelay<NavigationBarStyle>
    
    public var rightMenus: BehaviorRelay<[MenuData]?>
    
    /// page转场动画
    public let transitionType: String?
    
    /// 是否允许滑动返回, true 允许, false 禁止, 默认true
    public var interactivePop: Bool
    
    public var backgroundColor: UIColor
    
    /// 标题变更通知
    public var titleObservable: PublishRelay<(String?, String?)> = PublishRelay()
    
    static func create(map: [String: Any]?) -> PageConfig {
        guard let map = map else {
            return PageConfig()
        }
        
        let titleAlignment: TitleAlignment
        if let titleAlignmentStr = map["titleAlignment"] as? String {
            titleAlignment = TitleAlignment(rawValue: titleAlignmentStr) ?? .center
        } else {
            titleAlignment = .center
        }
        
        let statusBarType: StatusBarType
        if let statusBarTypeStr = map["statusBarType"] as? String {
            statusBarType = StatusBarType(rawValue: statusBarTypeStr) ?? .light
        } else {
            statusBarType = .light
        }
        
        let navigationBarType: NavigationBarStyle.NavigationBarType
        if let navigationBarTypeStr = map["navigationBarType"] as? String {
            navigationBarType = NavigationBarStyle.NavigationBarType(rawValue: navigationBarTypeStr) ?? .opaque
        } else {
            navigationBarType = .opaque
        }
        
        let navigationBarBGColor: UIColor? = (map["navigationBarBGColor"] as? String)?.ex.color
        
        let navigationBarTintColor: UIColor? = (map["navigationBarTintColor"] as? String)?.ex.color
        
        let rightMenus: [MenuData]?
        if let rightMenusDic = map["rightMenus"] as? [String: Any] {
            rightMenus = try? CodableBuilder().createDictionaryDecoder().decode([MenuData].self, from: rightMenusDic)
        } else {
            rightMenus = nil
        }
        
        return PageConfig(title: map["title"] as? String,
                          subTitle: map["subTitle"] as? String,
                          titleAlignment: titleAlignment,
                          statusBarType: statusBarType,
                          navigationBarStyle: NavigationBarStyle(type: navigationBarType,
                                                                 backgroundColor: navigationBarBGColor, 
                                                                 tintColor: navigationBarTintColor),
                          rightMenus: rightMenus)
    }
    
    
    public init(name: String? = nil,
                title: String? = nil,
                subTitle: String? = nil,
                titleAlignment: TitleAlignment = .center,
                imageUrl: String? = nil,
                image: UIImage? = nil,
                selectedImage: UIImage? = nil,
                statusBarType: StatusBarType = .light,
                navigationBarStyle: NavigationBarStyle = NavigationBarStyle(type: .opaque),
                rightMenus: [MenuData]? = nil,
                transitionType: String? = nil,
                interactivePop: Bool = true,
                backgroundColor: UIColor = UIColor.white) {
        
        self.name = name
        self.title = title
        self.subTitle = subTitle
        self.titleAlignment = titleAlignment
        self.imageUrl = imageUrl
        self.image = image
        self.selectedImage = selectedImage
        self.statusBarType = BehaviorRelay(value: statusBarType)
        self.navigationBarStyle = BehaviorRelay(value: navigationBarStyle)
        self.rightMenus = BehaviorRelay(value: rightMenus)
        self.transitionType = transitionType
        self.interactivePop = interactivePop
        self.backgroundColor = backgroundColor
    }
    
    func set(map: [String: Any]) {
        if let title = map["title"] as? String,
           let subTitle = map["subTitle"] as? String {
            set(title: title, subTitle: subTitle)
        } else if let title = map["title"] as? String {
            set(title: title)
        } else if let subTitle = map["subTitle"] as? String {
            set(subTitle: subTitle)
        }
        
        if let titleAlignmentStr = map["titleAlignment"] as? String,
           let titleAlignment = TitleAlignment(rawValue: titleAlignmentStr) {
            self.titleAlignment = titleAlignment
        }
        
        if let statusBarTypeStr = map["statusBarType"] as? String,
           let statusBarType = StatusBarType(rawValue: statusBarTypeStr) {
            self.statusBarType.accept(statusBarType)
        }
        
        var navigationBarType: NavigationBarStyle.NavigationBarType?
        if let navigationBarTypeStr = map["navigationBarType"] as? String {
            navigationBarType = NavigationBarStyle.NavigationBarType(rawValue: navigationBarTypeStr)
        }
        
        let navigationBarBGColor: UIColor? = (map["navigationBarBGColor"] as? String)?.ex.color
        
        let navigationBarTintColor: UIColor? = (map["navigationBarTintColor"] as? String)?.ex.color
        
        if navigationBarType != nil || navigationBarBGColor != nil || navigationBarTintColor != nil {
            var navigationBarStyle = self.navigationBarStyle.value
            
            if let navigationBarType = navigationBarType {
                navigationBarStyle.type = navigationBarType
            }
            
            if let navigationBarBGColor = navigationBarBGColor {
                navigationBarStyle.backgroundColor = navigationBarBGColor
            }
            
            if let navigationBarTintColor = navigationBarTintColor {
                navigationBarStyle.tintColor = navigationBarTintColor
            }
            
            self.navigationBarStyle.accept(navigationBarStyle)
        }
        
        if let rightMenusList = map["rightMenus"] as? [[String: Any]] {
            let decoder = CodableBuilder().createDictionaryDecoder()
            self.rightMenus.accept(rightMenusList.compactMap({ try? decoder.decode(MenuData.self, from: $0) }))
        }
    }
    
    public func set(title: String?, subTitle: String?) {
        self.title = title
        self.subTitle = subTitle
        
        titleObservable.accept((title, subTitle))
    }
    
    public func set(title: String?) {
        self.title = title
        
        titleObservable.accept((title, subTitle))
    }
    
    public func set(subTitle: String?) {
        self.subTitle = subTitle
        
        titleObservable.accept((title, subTitle))
    }
    
    public func set(rightMenus: [MenuData]?) {
        self.rightMenus.accept(rightMenus)
    }
}
